/******************************************************************************* * Copyright (c) 2005, 2017 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.ui.tests.concurrency; import java.lang.reflect.InvocationTargetException; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.IWorkspaceRunnable; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jface.dialogs.ProgressMonitorDialog; import org.eclipse.jface.operation.IThreadListener; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.actions.WorkspaceModifyOperation; import junit.framework.TestCase; /** * Tests the following sequence of events: * 1) Lock is acquired in UI thread * 2) Modal context thread is started using IThreadListener * 3) Lock is transferred to modal context thread * 4) Modal context thread performs an asyncExec * 5) The asyncExec tries to acquire the same lock held by the modal context * 6) The modal context thread exits, thus transferring the rule back to the UI thread * <p> * Now the rule has been transferred back to the UI thread, but the UI thread * is in a wait loop waiting to obtain the rule. The UI thread should realize that * it now owns the lock it is waiting for, and continue with its execution. * <p> * See bug 98621 for more details. * @since 3.2 */ public class TestBug98621 extends TestCase { class TransferTestOperation extends WorkspaceModifyOperation implements IThreadListener { @Override public void execute(final IProgressMonitor pm) { Display.getDefault().asyncExec(() -> { try { workspace.run((IWorkspaceRunnable) mon -> { // }, workspace.getRoot(), IResource.NONE, null); } catch (CoreException ex) { ex.printStackTrace(); } }); //wait until the asyncExec is blocking the UI thread try { Thread.sleep(1000); } catch (InterruptedException e) { //ignore } } @Override public void threadChange(Thread thread) { Job.getJobManager().transferRule(workspace.getRoot(), thread); } } private IWorkspace workspace = ResourcesPlugin.getWorkspace(); public TestBug98621() { super(); } public TestBug98621(String name) { super(name); } /** * Performs the test */ public void testBug() throws CoreException { workspace.run((IWorkspaceRunnable) monitor -> { ProgressMonitorDialog dialog = new ProgressMonitorDialog(new Shell()); try { dialog.run(true, false, new TransferTestOperation()); } catch (InvocationTargetException e1) { e1.printStackTrace(); fail(e1.getMessage()); } catch (InterruptedException e2) { // ignore } }, workspace.getRoot(), IResource.NONE, null); } }